package lk.icta.user.service;

import lk.icta.core.entity.Organization;
import lk.icta.user.common.AuthorizationException;
import lk.icta.user.entity.User;

import java.util.List;

/**
 * @author Mahesha Kalpanie
 * @author Supun Nimesh Karunathilaka
 */
public interface UserManager {
    /**
     * Create a new user
     *
     * @param userToCreate the User instance to create
     * @param adminUser    the user account creating the new user - must belong to role ADMIN
     */
    void createUser(User userToCreate, User adminUser);

    /**
     * Find a user from his/her userName
     *
     * @param userName
     * @return User corresponding to the given username
     */
    public User getUserByUserName(String userName);

    /**
     * Update a user
     *
     * @param userToUpdate the User instance to update
     * @param adminUser    the user account creating the new user - must belong to role ADMIN
     */
    void updateUser(User userToUpdate, User adminUser);

    /**
     * Delete a user. Will mark this record as permanently removed, and then maintained for historical
     * and reporting/auditing purposes
     *
     * @param userToDelete the User instance to delete
     * @param adminUser    the user account creating the new user - must belong to role ADMIN
     */
    void deleteUser(User userToDelete, User adminUser);

    /**
     * Update the password of the user, along with a new password expiry date
     *
     * @param newPass the new password
     * @param user    user account
     */
    void updatePassword(String newPass, User user);

    /**
     * Authenticate user credentials
     *
     * @param userName the user name
     * @param password the password
     * @return the User object if authorization succeeds
     * @throws AuthorizationException if authorization fails
     */
    User authenticateUser(String userName, String password) throws AuthorizationException;

    /**
     * Get all users (non-deleted accounts)
     *
     * @return all non-deleted Users
     */
    public List<User> getAllUsers();

    /**
     * Hash the password
     *
     * @param password pasword in clear text
     * @return hashed password
     */
    public String hashPassword(String password);

    /**
     * get ORPII user list for each organization
     *
     * @param organizationId related organization id
     * @param user           user
     * @return ORPII user list
     */
    public List<User> getUsersByOrganization(int organizationId, User user);

    /**
     * get ORPII user list for each organization
     *
     * @param organizationId related organization id
     * @param user           user
     * @return ORPII user list
     */
    public List<User> getORPIIUsersByOrganization(int organizationId, User user);

    /**
     * get URMGOI user list for each organization
     *
     * @param organizationId related organization id
     * @param user           user
     * @return ORPII user list
     */
    public List<User> getNewURMGOIUsersByOrganization(int organizationId, User user);

    /**
     * For active user
     *
     * @param user           user to be active
     * @param requestingUser requesting User for active a user
     */
    public void activeUser(User user, User requestingUser);


    /**
     * For inactive user
     *
     * @param user           user to be inactive
     * @param requestingUser requesting User for inactive a user
     */
    public void inactiveUser(User user, User requestingUser);

    /**
     * Update the preferred language of the user
     *
     * @param prefLanguage the new preferred language
     * @param user         user account
     */
    void updatePreferredLanguage(String prefLanguage, User user);

    /**
     * Filter user by user role
     *
     * @param role role id of the user
     * @param user requesting User for
     * @return filtered user list by user role
     */
    public List<User> getUsersByRole(String role, User user);

    /**
     * Create a new user
     *
     * @param userToCreate   the User instance to create
     * @param adminUser      the user account creating the new user - must belong to role ADMIN
     * @param roleId         role id assigned to the user
     * @param randomPassword generated random password for the new user
     */
    void createUser(User userToCreate, User adminUser, String roleId, String randomPassword);

    /**
     * Filter user by DS
     *
     * @param role role id of the user
     * @param dsId division id of the user
     * @param user requesting User for
     * @return filtered user list by user role
     */
    public List<User> getUsersByRoleDS(String role,int dsId, User user);
}
